using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using System.Data;
using System.Linq;
using System.Data.Linq;
using System.Data.Objects.DataClasses;

using VietPublisher.BSL.BK;
using VietPublisher.Web.Controls;
using VietPublisher.API.Membership;
using VietPublisher.BSL.BK;
using VietPublisher.Repositories.Interface;
using VietPublisher.BaseProject;
using VietPublisher.BaseProject.Utils.Miscellaneous;


namespace VietPublisher.Web.Framework
{
    public enum ValidationType
    {
        Create,
        Edit,
        Delete
    }

    public abstract class StringBaseEntityController : Controller
    {

        #region Repository

        #region Repository Account
        IAccountRepository _RepoAccount;
        public IAccountRepository RepoAccount
        {
            get
            {
                if (_RepoAccount == null)
                {
                    _RepoAccount = new AccountRepository();
                }
                return _RepoAccount;
            }
        }
        #endregion

        #region Repository Book
        IBookRepository _RepoBook;
        public IBookRepository RepoBook
        {
            get
            {
                if (_RepoBook == null)
                {
                    _RepoBook = new BookRepository();
                }
                return _RepoBook;
            }
        }
        #endregion

        #region Repository Order
        IOrderRepository _RepoOrder;
        public IOrderRepository RepoOrder
        {
            get
            {
                if (_RepoOrder == null)
                {
                    _RepoOrder = new OrderRepository();
                }
                return _RepoOrder;
            }
        }
        #endregion

        #region Repository Publisher
        IPublisherRepository _RepoPublisher;
        public IPublisherRepository RepoPublisher
        {
            get
            {
                if (_RepoPublisher == null)
                {
                    _RepoPublisher = new PublisherRepository();
                }
                return _RepoPublisher;
            }
        }
        #endregion

        #region Repository Category
        ICategoryRepository _RepoCategory;
        public ICategoryRepository RepoCategory
        {
            get
            {
                if (_RepoCategory == null)
                {
                    _RepoCategory = new CategoryRepository();
                }
                return _RepoCategory;
            }
        }
        #endregion

        #region Repository Author
        IAuthorRepository _RepoAuthor;
        public IAuthorRepository RepoAuthor
        {
            get
            {
                if (_RepoAuthor == null)
                {
                    _RepoAuthor = new AuthorRepository();
                }
                return _RepoAuthor;
            }
        }
        #endregion

        #region Repository Cart
        ICartRepository _RepoCart;
        public ICartRepository RepoCart
        {
            get
            {
                if (_RepoCart == null)
                {
                    _RepoCart = new CartRepository();
                }
                return _RepoCart;
            }
        }
        #endregion

        #endregion

        #region Private & Utilities

        private bool IsTrue(bool? value)
        {
            return !value.HasValue || value.Value;
        }

        public Guid ToGuid(string id)
        {
            if (!string.IsNullOrEmpty(id))
            {
                try
                {
                    return new Guid(id);
                }
                finally
                {
                }
            }
            return Guid.Empty;
        }

        public Guid[] ToGuids(string ids)
        {
            List<Guid> guids = new List<Guid>();
            var idArr = ids.Split(new char[] { ',', ' ', ';' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string id in idArr)
            {
                try
                {
                    guids.Add(new Guid(id));
                }
                catch
                {

                }
            }
            return guids.ToArray();
        }

        public int? GetParamInt(string name)
        {
            string param = HttpContext.Request[name];
            if (!string.IsNullOrEmpty(param))
            {
                int value = 0;
                if (int.TryParse(param, out value))
                {
                    return value;
                }
            }
            return null;
        }

        public Guid? GetParamGuid(string name)
        {
            string param = HttpContext.Request[name];
            if (!string.IsNullOrEmpty(param))
            {
                try
                {
                    return new Guid(param);
                }
                finally
                {
                }
            }
            return null;
        }

        protected virtual EntityKeyMember[] ConvertStringToId(string idString)
        {
            string[] keys = idString.Split(',');
            int count = keys.Length;
            EntityKeyMember[] keysEntity = new EntityKeyMember[count];
            try
            {
                for (int i = 0; i < count; i++)
                {
                    string[] keyMember = keys[i].Split(' ');
                    keysEntity[i] = new EntityKeyMember(keyMember[0], keyMember[1]);
                }
                return keysEntity;
            }
            catch
            {
                return new EntityKeyMember[] { new EntityKeyMember("Id", ToGuid(idString)) };
            }
        }

        /// <summary>
        /// Store session info
        /// </summary>
        /// <param name="userName"></param>
        protected void StoreSessionInfo()
        {

            var emp = this.CurrentUser();

            if (emp != null)
            {
                Session[DConst.currentUserId] = emp.UserId;
                Session[DConst.email] = emp.Email;
                Session[DConst.role] = emp.UserTypes;
                Session[DConst.userName] = emp.UserName;
                //var MembershipService = new MembershipAPI();
                //string password = MembershipService.GetPassword(emp.UserName, emp.Email);
                //Session["Password"] = password;
                
            }
        }
        #endregion

        public StringBaseEntityController()
        {
        }

        public string Email
        {
            get
            {
                return Session[DConst.email].ToString();
            }
        }

        //public string Password
        //{
        //    get
        //    {
        //        return Session["Password"].ToString();
        //    }
        //}

        public string UserName
        {
            get
            {
                return Session[DConst.userName]== null? string.Empty: Session[DConst.userName].ToString();
            }
        }

        protected override PartialViewResult PartialView(string viewName, object model)
        {
            viewName = LocalizeViewName(viewName, null);
            return base.PartialView(viewName, model);
        }

        private string LocalizeViewName(string viewName, string masterName)
        {
            if (this.ControllerContext == null) return viewName;

            if (string.IsNullOrEmpty(viewName))
            {
                viewName = this.ControllerContext.Controller.ValueProvider.GetValue("action").RawValue.ToString();
            }
            string cultureName = this.CurrentLanguage().Substring(0, 2);

            if (cultureName == "ko")
            {
                cultureName = string.Empty;
            }
            else
            {
                cultureName = "." + cultureName;
            }
            string view = viewName + cultureName;

            ViewEngineResult result = ViewEngines.Engines.FindView(this.ControllerContext, view, masterName);
            if (result.View == null)
            {
                view = viewName;
            }

            return view;
        }
        protected override ViewResult View(string viewName, string masterName, object model)
        {
            viewName = LocalizeViewName(viewName, masterName);
            return base.View(viewName, masterName, model);
        }

        //  protected override void OnActionExecuting(ActionExecutingContext filterContext)
        //   {

        /*
        string requestUrl = filterContext.RequestContext.HttpContext.Request.Url.ToString();
        bool isSessionEnded = Session[DConst.userName] == null || Session[DConst.email] == null;
        bool isOtherPage = !requestUrl.ToLower().Contains("logon");
            
        if (isSessionEnded && isOtherPage)
        {
            var session = filterContext.RequestContext.HttpContext.Session;

            session.Clear();
            Response.Redirect("~/Account/Logon");
            return;
        }*/
        /*
        var session = filterContext.RequestContext.HttpContext.Session;
        if (session != null)
        {
            string requestUrl = filterContext.RequestContext.HttpContext.Request.Url.ToString();
            bool isSessionEnded = false;// Session[DConst.userName] == null;
            bool isOtherPage = !requestUrl.ToLower().Contains("logon");

            if (session.IsNewSession)
            {
                string sessionCookie = filterContext.RequestContext.HttpContext.Request.Headers["Cookie"];
                isSessionEnded |= null != sessionCookie && sessionCookie.IndexOf("ASP.NET_SessionId") >= 0;

                if (isSessionEnded && isOtherPage)
                {
                    session.Clear();
                    Response.Redirect("~/Account/Logon");
                    return;
                }

            }

            StoreSessionInfo();
        }*/

        //if (!IsAuthorized())
        //{
        //    Response.Redirect("~/");
        //    return;
        //}

        //StoreSessionInfo();
        //  base.OnActionExecuting(filterContext);
        //  }


        //protected virtual bool Validate(T item, ValidationType validationType)
        //{
        //    return ModelState.IsValid;
        //}

        public virtual ActionResult BlankAction(string viewName)
        {
            return View(viewName);
        }

        /// <summary>
        /// Get Request Form
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public String GetRequestForm(string param)
        {
            return Request.Form[param] != null ? Request.Form[param].ToString() : "";
        }

        /// <summary>
        /// Get Request Param
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public String GetRequestParam(string param)
        {
            return Request.Params[param] != null ? Request.Params[param].ToString() : "";
        }

        /// <summary>
        /// Check if user has authorization to access thi page or not
        /// </summary>
        /// <returns></returns>
        protected bool IsAuthorized()
        {
            return true;
            /*
            bool hasPermission = true;
            en_SC_MenuPermission[] allMenus = null;
            var menus = HttpContext.Session["PermitMenus"];
            if (menus != null)
            {
                allMenus = menus as en_SC_MenuPermission[];
            }

            if (allMenus != null)
            {
                string action = this.ValueProvider.GetValue("action").RawValue.ToString().ToLower();
                string controller = ValueProvider.GetValue("controller").RawValue.ToString().ToLower();

                if (controller != "home" && action != "logon")
                {
                    var menu = allMenus.FirstOrDefault(p => (p.Controller ?? string.Empty).ToLower()  == controller 
                        && (p.Action ?? string.Empty).ToLower() == action);
                    hasPermission = menu != null;                    
                }
                else
                {
                    hasPermission = true;
                }
            }

            return hasPermission;
             * 
             * */
        }
    }

    #region Class Authorize
    [Serializable]
    [Flags]
    public enum SiteRoles
    {
        Guest = -1,
        Customer = BaseProject.Enums.UserTypes.CUSTOMER,
        Admin = BaseProject.Enums.UserTypes.ADMIN,
    }
    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        // the "new" must be used here because we are hiding
        // the Roles property on the underlying class
        public new SiteRoles Roles;

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext == null)
                throw new ArgumentNullException("httpContext");

            // string[] users = Users.Split(',');

            //==== code cu~
            //if (!httpContext.User.Identity.IsAuthenticated)
            //    return false;

            var tempRole = httpContext.Session["role"] ?? SiteRoles.Guest;
            SiteRoles role = (SiteRoles)tempRole;
            //== Write to log
            //if (role == SiteRoles.Guest && httpContext.Session["IsGuest"] == null)
            //{
            //    httpContext.Session["IsGuest"] = true;

            //    Account.StoreSessionInfo();
            //    //Account.AccessLog(Guid.Empty, "Login", true, "IP Guest");
            //}
            //==end
            //if (Roles != 0 && ((Roles & role) != role))
            //{
            // if (role == SiteRoles.Admin || (Roles == role))
            //if Admin is all Role
            if (role == SiteRoles.Admin || Roles == role)
            //if(Roles== role)
            {
                return true;
            }
            return false;
            //}

            //return true;
        }

    }
    #endregion
}
